package com.xhc.demo.service;

import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.xhc.demo.GlobalConfig;
import com.xhc.demo.entity.Order;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.UUID;

@Service
public class WxPayService {
    private static final Logger logger = LoggerFactory.getLogger(WxPayService.class);
    private final JsapiServiceExtension jsapiService;
    
    public WxPayService() {
        logger.info("[PAY] WxPayService initializing...");
        try {
            // 初始化配置
            Config config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(GlobalConfig.PAY_MCHID)           // 商户号
                    .privateKeyFromPath("/home/photo/pay/apiclient_key.pem")  // 私钥文件
                    .merchantSerialNumber(GlobalConfig.PAY_SERIAL_NO)         // 商户证书序列号
                    .apiV3Key(GlobalConfig.PAY_API_v3)           // API v3密钥
                    .build();
            
            // 初始化支付服务
            this.jsapiService = new JsapiServiceExtension.Builder()
                    .config(config)
                    .signType("RSA") // 不填默认为RSA
                    .build();
            logger.info("[PAY] WxPayService initialized successfully");
            
            // 打印配置信息以便调试
            logger.info("[PAY] Configuration: merchantId={}, serialNo={}", 
                GlobalConfig.PAY_MCHID, 
                GlobalConfig.PAY_SERIAL_NO);
                
        } catch (Exception e) {
            logger.error("[PAY] Failed to initialize WxPayService", e);
            throw new RuntimeException("Failed to initialize WxPayService", e);
        }
    }
    
    public JSONObject createPrePayOrder(Order order, String openid) throws Exception {
        logger.info("[PAY] Creating prepay order for order: {}", order);
        
        // 构建支付请求
        PrepayRequest request = new PrepayRequest();
        request.setAppid(GlobalConfig.APP_ID);
        request.setMchid(GlobalConfig.PAY_MCHID);
        request.setDescription("照片打印服务");
        request.setOutTradeNo(order.getPayOrderNumber());
        request.setNotifyUrl("https://p.mrxxhc.cn/api/users/wx_pay_notify");
        
        // 添加自定义参数
        JSONObject attachData = new JSONObject();
        attachData.put("orderId", order.getOrderId());
        attachData.put("payOrderNumber", order.getPayOrderNumber());
        attachData.put("amount", order.getAmount());

        request.setAttach(attachData.toString());
        
        // 设置金额
        Amount amount = new Amount();
        amount.setTotal(order.getAmount().multiply(new java.math.BigDecimal(100)).intValue());
        amount.setCurrency("CNY");
        request.setAmount(amount);
        
        // 设置支付者
        Payer payer = new Payer();
        payer.setOpenid(openid);
        request.setPayer(payer);
        
        // 调用统一下单接口并获取调起支付参数
        logger.info("[PAY] Sending prepay request: {}", request);
        PrepayWithRequestPaymentResponse response = jsapiService.prepayWithRequestPayment(request);
        
        // 将响应转换为JSONObject
        JSONObject payParams = new JSONObject();
        payParams.put("appId", response.getAppId());
        payParams.put("timeStamp", response.getTimeStamp());
        payParams.put("nonceStr", response.getNonceStr());
        payParams.put("package", response.getPackageVal());
        payParams.put("signType", response.getSignType());
        payParams.put("paySign", response.getPaySign());
        
        logger.info("[PAY] Generated pay params: {}", response.toString());
        return payParams;
    }
}
